package errors

import (
	goErrors "errors"
	"fmt"

	"yingsheng.com/go-api-server/utils"
)

type SysErrorInterface interface {
	Error() string
	String() string
	Status() int
}

type NormalErrorInterface interface {
	Error() string
	Status() int
}

type RecoverErrorInterface interface {
	Error() string
	SetError(msg string)
}

// 兼容系统原有错误对象
func New(text string) error {
	return goErrors.New(text)
}

var StopError = goErrors.New("ctrl stop")

// 创建系统错误对象
func NewSys(options ...interface{}) error {
	var (
		status    int
		simpleMsg string
		fullMsg   string
	)

	num := utils.NewRandomNum(6)

	for i, n := 0, len(options); i < n; i++ {
		switch opt := options[i].(type) {
		case int:
			status = opt
		default:
			simpleMsg = fmt.Sprintf("系统错误：%v", num)
			fullMsg = fmt.Sprintf("系统错误[%v]：%v", num, opt)
		}
	}

	return &SysError{
		status:    status,
		simpleMsg: simpleMsg,
		fullMsg:   fullMsg,
	}
}

// 系统错误对象
type SysError struct {
	simpleMsg string
	fullMsg   string
	status    int
}

// 实现错误信息接口
func (e *SysError) Error() string {
	return e.simpleMsg
}

// 真实错误信息
func (e *SysError) String() string {
	return e.fullMsg
}

// 错误状态码
func (e *SysError) Status() int {
	return e.status
}

// 普通错误对象
type NormalError struct {
	msg    string
	status int
}

// 创建普通错误对象
func NewNormal(options ...interface{}) error {
	var (
		status int
		msg    string
	)

	for i, n := 0, len(options); i < n; i++ {
		switch opt := options[i].(type) {
		case int:
			status = opt
		default:
			msg = fmt.Sprintf("%v", opt)
		}
	}

	return &NormalError{
		status: status,
		msg:    msg,
	}
}

func (e *NormalError) Error() string {
	return e.msg
}

func (e *NormalError) Status() int {
	return e.status
}

type RecoverError struct {
	msg string
}

func NewRecover() RecoverErrorInterface {
	return &RecoverError{}
}

func (e *RecoverError) Error() string {
	return e.msg
}

func (e *RecoverError) SetError(msg string) {
	e.msg = msg
}

//// 主动中断操作的错误指令
//type StopError interface {
//	error
//	IsError() bool
//}

//type stopError struct {
//	content string
//	isError bool
//}

//// 是否错误信息，影响控制台及日志记录方式
//func (a *stopError) IsError() bool {
//	return a.isError
//}
//func (a *stopError) Error() string {
//	return fmt.Sprintf("%v", a.content)
//}
